package org.mili.ticketeer.dao;

import org.mili.application.dao.AbstractDao;
import org.mili.application.dao.DaoException;
import org.mili.application.dao.DaoFactory;
import org.mili.application.dao.MofificationType;
import org.mili.application.dao.RowTransformer;
import org.mili.application.dao.query.QueryBuilder;
import org.mili.ticketeer.dto.Contact;
import org.mili.ticketeer.dto.ContactTicket;
import org.mili.application.dto.Identifieable;
import org.mili.ticketeer.dto.Ticket;
import org.mili.application.util.Lambda;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;

public class ContactTicketDao extends AbstractDao {
    private ContactDao contactDao = DaoFactory.getDao(ContactDao.class);

    public ContactTicketDao() {
        super(ContactTicket.UniqueFields.values(), ContactTicket.Fields.values(), ContactTicket.TABLE);
    }

    public Boolean assign(final Contact contact, final Ticket ticket) throws DaoException {
        return doInDao(new Lambda<Boolean>() {
            @Override
            public Boolean exec(Object... params) throws SQLException, DaoException {
                ContactTicket contactTicket = new ContactTicket();
                contactTicket.setContact(contact.getId());
                contactTicket.setTicket(ticket.getId());
                boolean result = update("insert into `contact_ticket` (`contact`, `ticket`) values(?, ?);", contact.getId(), ticket.getId()) == 1;
                boolean archive = archive(contactTicket, MofificationType.CREATE) == 1;
                return result && archive;
            }
        });
    }

    public List<Contact> getAssignmentsFor(final Ticket ticket) throws DaoException {
        List<Integer> contacts = doInDao(new Lambda<List<Integer>>() {
            @Override
            public List<Integer> exec(Object... params) throws SQLException {
                return query(new RowTransformer() {
                    @Override
                    public Integer transform(ResultSet resultSet) throws SQLException {
                        return resultSet.getInt(ContactTicket.Fields.CONTACT.name());
                    }
                }, QueryBuilder.createQueryBuilder()
                        .select()
                        .fields(ContactTicket.Fields.CONTACT)
                        .from(ContactTicket.TABLE)
                        .where()
                        .eq(ContactTicket.Fields.TICKET, ticket.getId())
                        .build());
            }
        });
        if (contacts.size() == 0) {
            return Collections.emptyList();
        }
        return contactDao.read(
                new ContactDao.ContactRowTransformer(),
                QueryBuilder.createQueryBuilder()
                        .select()
                        .fields(Identifieable.Fields.ID, contactDao.getFields())
                        .from(Contact.TABLE)
                        .where()
                        .in(Identifieable.Fields.ID, contacts)
                        .build());
    }

}
